#include "Playhand.h"

Playhand::Playhand()
{

}

Playhand::Playhand(Cards &cards)
{
    // 1. 对扑克牌进行分类: 1张的, 2张, 3张, 4张有多少种
    classify(cards);
    // 2. 对牌型进行分类
    judgeCardType();
}

Playhand::Playhand(HandType type, Card::Rank pt, int extra)
{
    m_type = type;
    m_pt = pt;
    m_extra = extra;
}


#include <cstring>

void Playhand::classify(Cards &cards)
{
    std::vector<Card> list = cards.toCardList(Cards::SortType::Desc);
    int cardRecord[(int)Card::Rank::Rand_size];
    memset(cardRecord, 0, sizeof(int) * (int)Card::Rank::Rand_size);

    for(int i=0; i<list.size(); ++i)
    {
        Card c = list.at(i);
        cardRecord[(int)c.getRank()]++;
    }

    m_oneCard.clear();
    m_twoCard.clear();
    m_threeCard.clear();
    m_fourCard.clear();

    for(int i=0; i<(int)Card::Rank::Rand_size; ++i)
    {
        if(cardRecord[i] == 1)
        {
            m_oneCard.push_back((Card::Rank)i);
        }
        else if(cardRecord[i] == 2)
        {
            m_twoCard.push_back((Card::Rank)i);
        }
        else if(cardRecord[i] == 3)
        {
            m_threeCard.push_back((Card::Rank)i);
        }
        else if(cardRecord[i] == 4)
        {
            m_fourCard.push_back((Card::Rank)i);
        }
    }
}

void Playhand::judgeCardType()
{
    m_type = Hand_Unknown;
    m_pt = Card::Rank::Three;
    m_extra = 0;

    if(isPass())
    {
        m_type = Hand_Pass;
    }
    if(isSingle())
    {
        m_type = Hand_Single;
        m_pt = m_oneCard[0];
    }
    else if(isPair())
    {
        m_type = Hand_Pair;
        m_pt = m_twoCard[0];
    }
    else if(isTriple())
    {
        m_type = Hand_Triple;
        m_pt = m_threeCard[0];
    }
    else if(isTripleSingle())
    {
        m_type = Hand_Triple_Single;
        m_pt = m_threeCard[0];
    }
    else if(isTriplePair())
    {
        m_type = Hand_Triple_Pair;
        m_pt = m_threeCard[0];
    }
    else if(isPlane())
    {
        m_type = Hand_Plane;
        // 记录点数最小的牌
        m_pt = m_threeCard[0];
    }
    else if(isPlaneTwoSingle())
    {
        m_type = Hand_Plane_Two_Single;
        // 记录点数最小的牌
        m_pt = m_threeCard[0];
    }
    else if(isPlaneTwoPair())
    {
        m_type = Hand_Plane_Two_Pair;
        // 记录点数最小的牌
        m_pt = m_threeCard[0];
    }
    else if(isSeqPair())
    {
        m_type = Hand_Seq_Pair;
        // 记录点数最小的牌
        m_pt = m_twoCard[0];
        m_extra = m_twoCard.size();
    }
    else if(isSeqSingle())
    {
        m_type = Hand_Seq_Single;
        // 记录点数最小的牌
        m_pt = m_oneCard[0];
        m_extra = m_oneCard.size();
    }
    else if(isBomb())
    {
        m_type = Hand_Bomb;
        // 记录点数最小的牌
        m_pt = m_fourCard[0];
    }
    else if(isBombSingle())
    {
        m_type = Hand_Bomb_Single;
        // 记录点数最小的牌
        m_pt = m_fourCard[0];
    }
    else if(isBombPair())
    {
        m_type = Hand_Bomb_Pair;
        // 记录点数最小的牌
        m_pt = m_fourCard[0];
    }
    else if(isBombTwoSingle())
    {
        m_type = Hand_Bomb_Two_Single;
        // 记录点数最小的牌
        m_pt = m_fourCard[0];
    }
    else if(isBombJokers())
    {
        m_type = Hand_Bomb_Jokers;
    }
    else if(isBombJokersSingle())
    {
        m_type = Hand_Bomb_Jokers_Single;
    }
    else if(isBombJokersPair())
    {
        m_type = Hand_Bomb_Jokers_Pair;
    }
    else if(isBombJokersTwoSingle())
    {
        m_type = Hand_Bomb_Jokers_Two_Single;
    }
}

bool Playhand::isPass()
{
    if(m_oneCard.size() == 0 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.empty())
    {
        return true;
    }
    return false;
}

Playhand::HandType Playhand::getHandType()
{
    return m_type;
}

Card::Rank Playhand::getCardPoint()
{
    return m_pt;
}

int Playhand::getExtra()
{
    return m_extra;
}

bool Playhand::canBeat(const Playhand &other)
{
    // 我的牌型是未知的
    if(m_type == Hand_Unknown)
    {
        return false;
    }
    // 对方放弃出牌
    if(other.m_type == Hand_Pass)
    {
        return true;
    }
    // 我是王炸
    if(m_type == Hand_Bomb_Jokers)
    {
        return true;
    }
    if(m_type == Hand_Bomb && other.m_type >= Hand_Single && other.m_type <= Hand_Seq_Single)
    {
        return true;
    }
    // 双方的牌型一致
    if(m_type == other.m_type)
    {
        if(m_type == Hand_Seq_Pair || m_type == Hand_Seq_Single)
        {
            return m_pt > other.m_pt && m_extra == other.m_extra;
        }
        else
        {
            return m_pt > other.m_pt;
        }
    }
    return false;
}

//bool Playhand::canBeat(const Playhand &other)
//{
//    // 我的牌型是未知的
//    if(m_type == Hand_Unknown)
//    {
//        return false;
//    }
//    // 对方放弃出牌
//    if(other.m_type == Hand_Pass)
//    {
//        return true;
//    }
//    // 我是王炸
//    if(m_type == Hand_Bomb_Jokers)
//    {
//        return true;
//    }
//    if(m_type == Hand_Bomb && other.m_type >= Hand_Single && other.m_type <= Hand_Seq_Single)
//    {
//        return true;
//    }
//    // 双方的牌型一致
//    if(m_type == other.m_type)
//    {
//        if(m_type == Hand_Seq_Pair || m_type == Hand_Seq_Single)
//        {
//            return m_pt > other.m_pt && m_extra == other.m_extra;
//        }
//        else
//        {
//            return m_pt > other.m_pt;
//        }
//    }
//    return false;
//}

bool Playhand::isSingle()
{
    if(m_oneCard.size() == 1 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.empty())
    {
        return true;
    }
    return false;
}

bool Playhand::isPair()
{
    if(m_oneCard.empty() && m_twoCard.size() == 1 && m_threeCard.empty() && m_fourCard.empty())
    {
        return true;
    }
    return false;
}

bool Playhand::isTriple()
{
    if(m_oneCard.empty() && m_twoCard.empty() && m_threeCard.size() == 1 && m_fourCard.empty())
    {
        return true;
    }
    return false;
}

bool Playhand::isTripleSingle()
{
    if(m_oneCard.size() == 1 && m_twoCard.empty() && m_threeCard.size() == 1 && m_fourCard.empty())
    {
        return true;
    }
    return false;
}

bool Playhand::isTriplePair()
{
    if(m_oneCard.empty() && m_twoCard.size() == 1 && m_threeCard.size() == 1 && m_fourCard.empty())
    {
        return true;
    }
    return false;
}

bool Playhand::isPlane()
{
    if(m_oneCard.empty() && m_twoCard.empty() && m_threeCard.size() == 2 && m_fourCard.empty())
    {
        std::sort(m_threeCard.begin(), m_threeCard.end());
        //判断飞机中没有3个 “2”
        if((int)m_threeCard[1] - (int)m_threeCard[0] == 1 && m_threeCard[1] < Card::Rank::Two)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isPlaneTwoSingle()
{
    if(m_oneCard.size() == 2 && m_twoCard.empty() && m_threeCard.size() == 2 && m_fourCard.empty())
    {
        std::sort(m_threeCard.begin(), m_threeCard.end());
        std::sort(m_oneCard.begin(), m_oneCard.end());
        //判断带的单张是不是大小王
        if((int)m_threeCard[1] - (int)m_threeCard[0] == 1 && m_threeCard[1] < Card::Rank::Two &&
                m_oneCard[0] != Card::Rank::Joker_min && m_oneCard[1] != Card::Rank::Joker_max)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isPlaneTwoPair()
{
    if(m_oneCard.empty() && m_twoCard.size() == 2 && m_threeCard.size() == 2 && m_fourCard.empty())
    {
        std::sort(m_threeCard.begin(), m_threeCard.end());
        if((int)m_threeCard[1] - (int)m_threeCard[0] == 1 && m_threeCard[1] < Card::Rank::Two)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isSeqPair()
{
    if(m_oneCard.empty() && m_twoCard.size() >= 3 && m_threeCard.empty() && m_fourCard.empty())
    {
        std::sort(m_twoCard.begin(), m_twoCard.end());
        //判断牌是否连续 用最大的牌减去最小的牌，看是否等于牌的总数减一
        if((int)m_twoCard.back() - (int)m_twoCard.front() == ((int)m_twoCard.size() - 1) &&
                m_twoCard.front() >= Card::Rank::Three && m_twoCard.back() < Card::Rank::Two)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isSeqSingle()
{
    if(m_oneCard.size() >= 5 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.empty())
    {
        std::sort(m_oneCard.begin(), m_oneCard.end());
        if((int)m_oneCard.back() - (int)m_oneCard.front() == (m_oneCard.size() -1) &&
                m_oneCard.front() >= Card::Rank::Three && m_oneCard.back() < Card::Rank::Two)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isBomb()
{
    if(m_oneCard.empty() && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.size() == 1)
    {
         return true;
    }
    return false;
}

bool Playhand::isBombSingle()
{
    if(m_oneCard.size() == 1 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.size() == 1)
    {
         return true;
    }
    return false;
}

bool Playhand::isBombPair()
{
    if(m_oneCard.empty() && m_twoCard.size() == 1 && m_threeCard.empty() && m_fourCard.size() == 1)
    {
         return true;
    }
    return false;
}

bool Playhand::isBombTwoSingle()
{
    if(m_oneCard.size() == 2 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.size() == 1)
    {
        std::sort(m_oneCard.begin(), m_oneCard.end());
        if(m_oneCard.front() != Card::Rank::Joker_min && m_oneCard.back() != Card::Rank::Joker_max)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isBombJokers()
{
    if(m_oneCard.size() == 2 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.empty())
    {
        std::sort(m_oneCard.begin(), m_oneCard.end());
        if(m_oneCard.front() == Card::Rank::Joker_min && m_oneCard.back() == Card::Rank::Joker_max)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isBombJokersSingle()
{
    if(m_oneCard.size() == 3 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.empty())
    {
        std::sort(m_oneCard.begin(), m_oneCard.end());
        if(m_oneCard[1] == Card::Rank::Joker_min && m_oneCard[2] == Card::Rank::Joker_max)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isBombJokersPair()
{
    if(m_oneCard.size() == 2 && m_twoCard.size() == 1 && m_threeCard.empty() && m_fourCard.empty())
    {
        std::sort(m_oneCard.begin(), m_oneCard.end());
        if(m_oneCard[0] == Card::Rank::Joker_min && m_oneCard[1] == Card::Rank::Joker_max)
        {
            return true;
        }
    }
    return false;
}

bool Playhand::isBombJokersTwoSingle()
{
    if(m_oneCard.size() == 4 && m_twoCard.empty() && m_threeCard.empty() && m_fourCard.empty())
    {
        std::sort(m_oneCard.begin(), m_oneCard.end());
        if(m_oneCard[2] == Card::Rank::Joker_min && m_oneCard[3] == Card::Rank::Joker_max)
        {
            return true;
        }
    }
    return false;
}


